Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document the crossplane.io/external-create-... annotations #688

Merged
merged 11 commits into from
Feb 1, 2024

Conversation

negz
Copy link
Member

@negz negz commented Jan 30, 2024

These annotations were introduced in crossplane/crossplane-runtime#283.

Per crossplane/crossplane#3037 folks find these annotations hard to reason about. That's understandable, because they're doing a lot of subtle things.

This section ended up super long, but I think this is an area where folks really need to understand what's happening in order to make good decisions when Crossplane refuses to proceed.

These annotations were introduced in crossplane/crossplane-runtime#283.

Per crossplane/crossplane#3037 folks find
these annotations hard to reason about. That's understandable, because
they're doing a lot of subtle things.

This section ended up super long, but I think this is an area where
folks really need to understand what's happening in order to make good
decisions when Crossplane refuses to proceed.

Signed-off-by: Nic Cope <nicc@rk0n.org>
Copy link

netlify bot commented Jan 30, 2024

Deploy Preview for crossplane ready!

Name Link
🔨 Latest commit 0aef9a6
🔍 Latest deploy log https://app.netlify.com/sites/crossplane/deploys/65bab181d4fc2d0008fed4c6
😎 Deploy Preview https://deploy-preview-688--crossplane.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 89 (no change from production)
Accessibility: 88 (🔴 down 3 from production)
Best Practices: 83 (no change from production)
SEO: 93 (no change from production)
PWA: 70 (no change from production)
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Collaborator

@plumbis plumbis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions and some edits just to make some of the writing more direct. Nothing major. Great content!

content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
@negz
Copy link
Member Author

negz commented Jan 31, 2024

@plumbis PTAL. I started addressing feedback and ended up with a fairly extensive refactoring.

Signed-off-by: Nic Cope <nicc@rk0n.org>
@@ -635,21 +635,145 @@ my-rds-instance True True my-custom-name 11m

### Creation annotations

Providers create new managed resources with the
`crossplane.io/external-create-pending` annotation.
In some rare situations a provider can forget that it created a resource. When
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the use of "rare" (subjective) or "forget" (anthropomorphic) .

Rare sounds non-deterministic. It may require a specific sequence but the sequence is known and should be described. It may be rare in general but when you are hitting all the time hearing it's "rare" is very frustrating.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Point taken. Reworded to avoid "rare" and "forgot".

That said, I would prefer if folks did not read this section and think "Crossplane's going to leak my resources all the time, I shouldn't trust it".

content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
Comment on lines 675 to 677
If the provider can't find a managed resource in an external system, it thinks
the resource doesn't exist. When the provider thinks a resource doesn't exist
it creates the resource.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If the provider can't find a managed resource in an external system, it thinks
the resource doesn't exist. When the provider thinks a resource doesn't exist
it creates the resource.
If the provider finds a managed resource with a
{{<hover label="creation" line="7">}}crossplane.io/external-name{{</hover>}}
annotation and doesn't find an external resource with a matching name, the
provider creates a new external resource.

Feel free to rework, but I think this should be "dumbed down" a bit and be more explicit.

  • What is the provider looking for in the external system?
  • How does that get connected to an MR?
  • Avoid "think"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked, PTAL.

I prefer not to mention external-name again explicitly here. It feels repetitive - how the provider looks up the MR - which is what the sentence immediately prior says.

"If the provider finds an MR with..." reads strangely to me too - MRs always have this annotation.

content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
content/master/concepts/managed-resources.md Outdated Show resolved Hide resolved
Signed-off-by: Nic Cope <nicc@rk0n.org>
Signed-off-by: Nic Cope <nicc@rk0n.org>
Signed-off-by: Nic Cope <nicc@rk0n.org>
Signed-off-by: Nic Cope <nicc@rk0n.org>
Signed-off-by: Nic Cope <nicc@rk0n.org>
Signed-off-by: Nic Cope <nicc@rk0n.org>
Signed-off-by: Nic Cope <nicc@rk0n.org>
Signed-off-by: Nic Cope <nicc@rk0n.org>
@negz negz requested a review from plumbis January 31, 2024 21:04
Copy link

@luxas luxas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for this write-up @negz 💯

Level triggered systems are very interesting 😄

One of my favorite presentations about this is from thockin (avoiding at-ing him here): https://speakerdeck.com/thockin/kubernetes-what-is-reconciliation

With that comes to mind, that how many Crossplane controllers are able to attach (in general, approximately) labels, annotations, or similar to their managed data in the external provider, such that they can (at least in theory), find and point out all of these leaked resources, as they can see that they are indeed owned by "me" (through that label or annotation in the external system), but there is no external-name reference to them in Kube?

This indeed, would require controllers to have some kind of "identity", however, which is probably a big challenge itself (such that two controllers in two different clusters could distinguish their managed objects in the external system).

`crossplane.io/external-create-failed` annotation after making the external API
call and receiving a response.
{{<hint "tip">}}
Crossplane calls resources that a provider creates but doesn't manage _leaked
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Crossplane calls resources that a provider creates but doesn't manage _leaked
Crossplane calls resources that a provider created but lost track of and therefore doesn't manage _leaked

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trying to word in such a way so that readers would understand instantly that this is an error case, without using the word "error", "exception" or "rare"


When the external system generates the resource's name, the provider attempts to
save it to the managed resource's `crossplane.io/external-name` annotation. If
it doesn't, it _leaks_ the resource.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it doesn't, it _leaks_ the resource.
it cannot (after multiple retries), it _leaks_ the resource.

Each time a provider reconciles a managed resource it checks the resource's
creation annotations. If the provider sees a create pending time that's more
recent than the most recent create succeeded or create failed time, it knows
that it might have leaked a resource.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any other common cases where this would happen than when someone went to the AWS UI and removed a reconciled bucket manually, and then Crossplane tried to recreate it, but failed to save the new name in the annotations?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, nothing comes to mind.

@negz
Copy link
Member Author

negz commented Feb 1, 2024

how many Crossplane controllers are able to attach (in general, approximately) labels, annotations, or similar to their managed data in the external provider, such that they can (at least in theory), find and point out all of these leaked resources, as they can see that they are indeed owned by "me" (through that label or annotation in the external system), but there is no external-name reference to them in Kube?

@luxas We considered this. It's a non-zero amount of controllers. However given:

  • The number of controllers (thousands)
  • The asymmetry of the APIs those controllers orchestrate (hundreds? thousands?)
  • That many of those APIs are eventually consistent (will take a while for reads to show results after a write)
  • The fact that many APIs that support tags/labels use a separate API call to add them (after create)

I'm skeptical there's value in exploring that path. Or at least it's deep into diminishing returns. At best we (Crossplane core) could offer some interface an ExternalClient (MR implementation) could optionally satisfy to lookup by label rather than by name and fall back to using that. It would then be up to any MR implementation that could to satisfy that interface (presumably by hand-writing the relevant code).

@negz
Copy link
Member Author

negz commented Feb 1, 2024

Thanks folks! We've spent a lot of time this week wordsmithing one this week. I like where it's at right now and I need to move on to other things, so I'm going to merge it as-is. 🙂

@negz negz merged commit 7a1ec9f into crossplane:master Feb 1, 2024
7 checks passed
@negz negz deleted the critical branch February 1, 2024 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants